"use client";
import type { Alert as AlertType } from "@/types/index";

import { useState, useEffect } from "react";
import { Image } from "@heroui/image";
import { Button } from "@heroui/button";
import { Alert } from "@heroui/alert";
import { EyeIcon, EyeSlashIcon } from "@heroicons/react/24/outline";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useRouter } from "next/navigation";
import cookie from "js-cookie";

import useCaptcha from "../../hooks/useCaptcha";

// 定义验证的规则
const registerSchema = z
  .object({
    username: z
      .string()
      .min(4, "用户名至少4个字符")
      .max(10, "用户名最多10个字符"),
    password: z
      .string()
      .min(6, "密码至少6个字符")
      .max(15, "密码最多15个字符")
      .regex(/^(?=.*[a-zA-Z])(?=.*\d)[A-Za-z\d]+$/, "密码必须包含字母和数字"),
    confirmPassword: z.string().min(6, "密码至少6个字符"),
    captcha: z.string().min(4, "验证码至少4个字符").max(4, "验证码最多4个字符"),
  })
  .refine((data) => data.password === data.confirmPassword, {
    message: "两次输入的密码不一致",
    path: ["confirmPassword"],
  });

const loginSchema = z.object({
  username: z
    .string()
    .min(4, "用户名至少4个字符")
    .max(10, "用户名最多10个字符"),
  password: z
    .string()
    .min(6, "密码至少6个字符")
    .max(15, "密码最多15个字符")
    .regex(/^(?=.*[a-zA-Z])(?=.*\d)[A-Za-z\d]+$/, "密码必须包含字母和数字"),
  captcha: z.string().min(4, "验证码至少4个字符").max(4, "验证码最多4个字符"),
});
// z.infer是zod提供的一个类型工具，用于根据zod schema推断出对应的TypeScript类型

type RegisterForm = z.infer<typeof registerSchema>;
type LoginForm = z.infer<typeof loginSchema>;
type Props = {
  showLogin: boolean;
  onChangeLogin: (showLogin: boolean) => void;
};

export default function LoginForm({ ...props }: Props) {
  const { showLogin, onChangeLogin } = props;

  useEffect(() => {
    refreshCaptcha();
  }, [showLogin]);
  const router = useRouter();
  const [showConfirm, setShowConfirm] = useState(false); // 是否显示确认密码
  const [showPassword, setShowPassword] = useState(false); // 是否显示密码
  // 验证码
  const [captchaUrl, refreshCaptcha] = useCaptcha();

  // 增加一个提示信息的状态
  const [alertInfo, setAlertInfo] = useState<AlertType>({
    color: "success",
    title: "注册成功，请登录",
    isShow: false,
  });

  const {
    register, // 注册表单验证规则
    handleSubmit, // 提交表单
    formState: { errors }, // 表单是否有错误
  } = useForm<RegisterForm>({
    resolver: zodResolver(registerSchema),
    mode: "onChange", // 表单验证模式，当输入框内容变化时验证
  });
  const {
    register: loginRegister,
    handleSubmit: loginHandleSubmit,
    formState: { errors: loginErrors },
  } = useForm<LoginForm>({
    resolver: zodResolver(loginSchema),
    mode: "onChange",
  });
  // 提交表单对应的逻辑
  const onSubmit = async (data: RegisterForm | LoginForm) => {
    try {
      if (showLogin) {
        const res = await fetch("/api/user/login", {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({
            username: data.username,
            password: data.password,
            captcha: data.captcha,
          }),
        });
        const result = await res.json();

        if (!result.code) {
          // 进入这个分支，说明登录成功
          const { token, userData } = result.data;

          localStorage.setItem("TOKEN", token);
          localStorage.setItem("USER", JSON.stringify(userData));

          // 将token存储到cookie中，设置期限为7天
          cookie.set("TOKEN", token, { expires: 7, path: "/" });
          router.push("/");
        } else {
          // 进入这个分支，说明登录失败
          setAlertInfo({
            color: "warning",
            title: "账号密码或验证码错误，请重试",
            isShow: true,
          });
          refreshCaptcha(); // 刷新验证码
        }
      } else {
        const response = await fetch("/api/user", {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({
            username: data.username,
            password: data.password,
            captcha: data.captcha,
          }),
        });

        const result = await response.json();

        if (!result.code) {
          // 进入这个分支，说明注册成功
          setAlertInfo({
            color: "success",
            title: "注册成功，请登录",
            isShow: true,
          });
          // 切换登录表单
          onChangeLogin(false);
        } else {
          // 进入这个分支，说明注册失败
          setAlertInfo({
            color: "danger",
            title: "注册失败，请重试",
            isShow: true,
          });
          refreshCaptcha(); // 刷新验证码
        }
      }
    } catch {
      setAlertInfo({
        color: "danger",
        title: "网络异常，请稍候再试",
        isShow: true,
      });
      refreshCaptcha(); // 刷新验证码
    }
  };

  return (
    <>
      {/* 提示框 */}
      {alertInfo.isShow && (
        <div className="fixed top-6 left-1/2 -translate-x-1/2 z-50">
          <Alert hideIcon color={alertInfo.color} title={alertInfo.title} />
        </div>
      )}
      {showLogin ? (
        <form className="space-y-5" onSubmit={loginHandleSubmit(onSubmit)}>
          {/* 用户名 */}
          <div>
            <label
              className="block text-sm font-medium text-gray-600 mb-1"
              htmlFor="username"
            >
              用户名
            </label>
            <input
              className="w-full px-4 py-2 border rounded focus:outline-none focus:ring focus:border-blue-400"
              id="username"
              placeholder="输入用户名"
              {...loginRegister("username")}
            />
            {loginErrors.username && (
              <p className="text-sm text-red-500 mt-1">
                {loginErrors.username.message}
              </p>
            )}
          </div>

          {/* 密码 */}
          <div>
            <label
              className="block text-sm font-medium text-gray-600 mb-1"
              htmlFor="password"
            >
              密码
            </label>
            <div className="relative">
              <input
                className="w-full px-4 py-2 border rounded focus:outline-none focus:ring focus:border-blue-400"
                id="password"
                placeholder="输入密码"
                type={showPassword ? "text" : "password"}
                {...loginRegister("password")}
              />
              <button
                className="absolute right-3 top-1/2 transform -translate-y-1/2 text-sm text-gray-500"
                type="button"
                onClick={() => setShowPassword((prev) => !prev)}
              >
                {showPassword ? (
                  <EyeSlashIcon className="h-5 w-5" />
                ) : (
                  <EyeIcon className="h-5 w-5" />
                )}
              </button>
            </div>
            {loginErrors.password && (
              <p className="text-sm text-red-500 mt-1">
                {loginErrors.password.message}
              </p>
            )}
          </div>

          {/* 验证码 */}
          <div className="flex gap-3 items-end">
            <div className="flex-1">
              <label
                className="block text-sm font-medium text-gray-600 mb-1"
                htmlFor="captcha"
              >
                验证码
              </label>
              <input
                className="w-full px-4 py-2 border rounded focus:outline-none focus:ring focus:border-blue-400"
                id="captcha"
                placeholder="请输入验证码"
                {...loginRegister("captcha")}
              />
              {loginErrors.captcha && (
                <p className="text-sm text-red-500 mt-1">
                  {loginErrors.captcha.message}
                </p>
              )}
            </div>
            <Image
              alt="captcha"
              className="h-[42px] w-[100px] cursor-pointer rounded border hover:opacity-80"
              src={captchaUrl}
              onClick={refreshCaptcha}
            />
          </div>

          {/* 登录按钮 */}
          <button
            className="w-full bg-blue-500 text-white py-2 rounded font-semibold hover:bg-blue-600 transition"
            type="submit"
          >
            登录
          </button>
        </form>
      ) : (
        <form className="space-y-5" onSubmit={handleSubmit(onSubmit)}>
          {/* 用户名 */}
          <div>
            <label
              className="block text-sm font-medium text-gray-600 mb-1"
              htmlFor="username"
            >
              用户名
            </label>
            <input
              className="w-full px-4 py-2 border rounded focus:outline-none focus:ring focus:border-blue-400"
              id="username"
              {...register("username")}
              placeholder="输入用户名"
            />
            {errors.username && (
              <p className="text-sm text-red-500 mt-1">
                {errors.username.message}
              </p>
            )}
          </div>

          {/* 密码 */}
          <div>
            <label
              className="block text-sm font-medium text-gray-600 mb-1"
              htmlFor="password"
            >
              密码
            </label>
            <div className="relative">
              <input
                className="w-full px-4 py-2 border rounded focus:outline-none focus:ring focus:border-blue-400"
                id="password"
                placeholder="输入密码"
                {...register("password")}
                type={showPassword ? "text" : "password"}
              />
              <button
                className="absolute right-3 top-1/2 transform -translate-y-1/2 text-sm text-gray-500"
                type="button"
                onClick={() => setShowPassword((prev) => !prev)}
              >
                {showPassword ? (
                  <EyeSlashIcon className="h-5 w-5" />
                ) : (
                  <EyeIcon className="h-5 w-5" />
                )}
              </button>
              {errors.password && (
                <p className="text-sm text-red-500 mt-1">
                  {errors.password.message}
                </p>
              )}
            </div>
          </div>

          {/* 确认密码 */}
          <div>
            <label
              className="block text-sm font-medium text-gray-600 mb-1"
              htmlFor="confirmPassword"
            >
              确认密码
            </label>
            <div className="relative">
              <input
                className="w-full px-4 py-2 border rounded focus:outline-none focus:ring focus:border-blue-400"
                id="confirmPassword"
                {...register("confirmPassword")}
                placeholder="再次确认密码"
                type={showConfirm ? "text" : "password"}
              />
              <button
                className="absolute right-3 top-1/2 transform -translate-y-1/2 text-sm text-gray-500"
                type="button"
                onClick={() => setShowConfirm((prev) => !prev)}
              >
                {showConfirm ? (
                  <EyeSlashIcon className="h-5 w-5" />
                ) : (
                  <EyeIcon className="h-5 w-5" />
                )}
              </button>
            </div>
            {errors.confirmPassword && (
              <p className="text-sm text-red-500 mt-1">
                {errors.confirmPassword.message}
              </p>
            )}
          </div>

          {/* 验证码 */}
          <div>
            <label
              className="block text-sm font-medium text-gray-600 mb-1"
              htmlFor="captcha"
            >
              验证码
            </label>
            <div className="flex gap-3">
              <div className="flex-1">
                <input
                  className="w-full px-4 py-2 border rounded focus:outline-none focus:ring focus:border-blue-400"
                  id="captcha"
                  {...register("captcha")}
                  placeholder="请输入验证码"
                />
                {errors.captcha && (
                  <p className="text-sm text-red-500 mt-1">
                    {errors.captcha.message}
                  </p>
                )}
              </div>
              <Image
                alt="captcha"
                className="h-[42px] w-[100px] cursor-pointer rounded border hover:opacity-80"
                src={captchaUrl}
                onClick={refreshCaptcha}
              />
            </div>
          </div>

          {/* 登录按钮 */}
          <Button className="w-full" color="primary" radius="lg" type="submit">
            注册
          </Button>
        </form>
      )}
    </>
  );
}
